package com.deman.framework.rpc.netty;

import com.deman.framework.rpc.config.DemanRpcProviderConfig;
import com.deman.framework.rpc.netty.handler.ServerInitChannel;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;





@Component
@ConditionalOnBean(value = {DemanRpcProviderConfig.class})
public class ServerStarter implements InitializingBean {
    Logger logger = LoggerFactory.getLogger(ServerStarter.class);
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workGroup = new NioEventLoopGroup();
    @Autowired
    private DemanRpcProviderConfig demanRpcProviderConfig;

    public void start() {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap.group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)
                    .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ServerInitChannel());
            ChannelFuture cf = serverBootstrap.bind(demanRpcProviderConfig.getPort()).sync();
            logger.info("Server Startup...");
            cf.channel().closeFuture().sync();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //优雅停机
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
            System.err.println("Sever ShutDown...");
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        new Thread(()->{
            this.start();
        }).start();
    }

    public static void main(String[] args) {
        ServerStarter serverStarter = new ServerStarter();
        serverStarter.start();
    }

}
